<?php
/**
 * @version		$Id: updatedata.php 10381 2008-10-01 03:35:53Z yopensource $
 * @package		YOS
 * @subpackage	Update Data
 * @author 		yopensource (yopensource@gmail.com)
 * @copyright	Copyright (C) 2005 - 2008 YOS. All rights reserved.
 * @license		Commercial
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die( 'Restricted access' );

jimport('joomla.application.component.model');

require_once(JPATH_COMPONENT_SITE.DS.'helpers'.DS.'phpWebHacks.php');
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'images.php');
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'get_image.php');
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'href.php');
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'tidy_clean.php');
require_once(JPATH_COMPONENT.DS.'helpers'.DS.'find_replace.php');
require_once(JPATH_COMPONENT_SITE.DS.'helpers'.DS.'resource_url.php');


// Set the table directory
//JTable::addIncludePath(JPATH_COMPONENT.DS.'tables');

/**
 * 
 *
 * @package		YOS
 * @subpackage	Update
 * @since 1.5
 */
JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables');
class FVBModelWorks extends JModel
{
	//component global configure:
  	//Licens, error...
  	private $_global_configure;
	
  	//to store list of todo jobs
  	private $_arr_jobs = array();
  	
	public function __construct(){
		parent::__construct();
		
		$config 		= &JComponentHelper::getParams('com_fvb_feed_manager');
		$this->_global_configure = $config;		
	}
	
	
	/**
	 * perform do all available jobs
	 *
	 * @return boolen
	 */
	public function works(){
		global $mainframe;
		if(JRequest::getInt('debug')){
			@error_reporting(E_ALL);
		}
		
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] check authorize BEGIN"); }
		if(!$this->_authorize()){
			$this->setError('[WORK] #1: Invalid update code');
			return false;
		}
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] check authorize END"); }
		
		//get jobs
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] get list of jobs BEGIN"); }
		if (!$this->_get_jobs()) {
			$this->setError('[WORK] #2: Can not get list of jobs');
			return false;
		}
		
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] get list of jobs END"); }
		
		if (!count($this->_arr_jobs)) {
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] empty jobs."); }
			return true;
		}
		
		//clean tmp dir
		if ($this->_clean_tmp_dir() === false) {
			return false;
		}
		
		//do jobs
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] do jobs BEGIN"); }
		if (!$this->_do_jobs()) {
			$this->setError('[WORK] #3: Do jobs fail');
			return false;
		}
		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] do jobs END"); }
	
		return true;
	}
	
	/**
	 * Clean the temp dir which store images received
	 *
	 * @return boolean.
	 */
	private function _clean_tmp_dir(){
		$config =& JFactory::getConfig();
		$tmp_path = $config->getValue('config.tmp_path').DS.'yos_news_crawler';
		
		if (JFolder::exists($tmp_path) === false) {
			return true;
		}
		
		if (JFolder::delete($tmp_path) === false) {
			$this->setError('[WORK] #4: Unable to delete temp directory: '. $tmp_path);
			return false;
		}
		
		if (JFolder::create($tmp_path) === false) {
			$this->setError('[WORK] #5: Unable to create temp directory: '. $tmp_path);
			return false;
		}
		
		return true;
	}
	
	/**
	 * check update code
	 *
	 * @return boolen
	 */
	private function _authorize(){
		//validate update code
		$config = $this->_global_configure;
		
		$code_update	= JRequest::getString('code');
		$config_code	= $config->get('code_update');		
		if (trim($config_code) != trim($code_update)) {			
			return false;
		}
		return true;
	}
	
	/**
	 * Get list of job tobe updated
	 *
	 * @return boolen
	 */
	private function _get_jobs(){		
		global $mainframe;
		if($this->_arr_jobs) return $this->_arr_jobs;
		
		$db	=& JFactory::getDBO();		
		$now	= JHTML::_('date','','%Y-%m-%d %H:%M:%S');
	
		// get job if published and is checkout or not checkout but checked_out_time>now;
		$query="SELECT *
				FROM `#__feeds` 
				WHERE published = 1 and (checked_out=0 or (checked_out<>0 and `checked_out_time` <= ".$db->Quote($now).")) 
				ORDER BY `last_update`
				LIMIT 0,3";
		$db->setQuery($query);
		
		$time_now		= JHTML::_('date','','%Y-%m-%d %H:%M:%S');
		
		$jobs = $db->loadObjectList();
		
			
		if ($db->getErrorNum()) {
			$arr_error = debug_backtrace();
			$this->setError('[WORK] MySQL error: '.$db->getErrorMsg()."\n FILE: ".$arr_error[0]['file']."\n LINE: ".$arr_error[0]['line']);
			return false;
		}
		
		if (!count($jobs)) {
			$this->setError('[WORK] There is not any job in database');
			return false;
		}
			$ip				=	$_SERVER['REMOTE_ADDR'];
			$fp = fopen( JPATH_COMPONENT_SITE.DS.'models'.DS.'log_work.txt', 'a');
			fputs($fp, "__________________________________________________\r\n");
			fputs($fp, "__________________________________________________\r\n");
			fputs($fp, "--------------------------------------------------\r\n");
			fputs($fp, "------Run time: $time_now ------\r\n");
			fputs($fp, "------From IP: $ip ------\r\n");
			$count	=	count($jobs);
			fputs($fp, "------Total jobs: $count ------\r\n");
		$dem	=	0;
		
		for ($i = 0; $i < count($jobs);$i++){	
				
			if (strtotime($jobs[$i]->last_update) + intval($jobs[$i]->time_update)*60 < strtotime($time_now)) {
				array_push($this->_arr_jobs, $jobs[$i]);
				
				$checked_out_time	=	$jobs[$i]->checked_out_time;				
				$txt	=	'id: '.$jobs[$i]->id.
							"\t|| Run:TRUE __".
							"\t|| title:".$jobs[$i]->title.							
							"\t|| c kout:".$jobs[$i]->checked_out.
							"\t|| c_out_time:".$checked_out_time.
							"\t|| l update:".$jobs[$i]->last_update.
							"\t|| t update:".$jobs[$i]->time_update;	
				$dem= $dem + 1;		
			}
			else {
				$txt	=	'id: '.$jobs[$i]->id.
							"\t|| Run:FALSE".	
							"\t|| title:".$jobs[$i]->title.							
							"\t|| c kout:".$jobs[$i]->checked_out.
							"\t|| l update:".$jobs[$i]->last_update.
							"\t|| t update:".$jobs[$i]->time_update;	
			}		
			fputs($fp, "\t\t $txt \r\n");
			
		}
		fputs($fp, "------Total job being run: $dem \r\n");
		fclose($fp);		
		return true;
	}

	/**
	 * Execute jobs
	 *
	 * @return boolen
	 */
  	private function _do_jobs()
  	{
  		global $mainframe;
  		$db		=	JFactory::getDBO();
  		$date	=	JFactory::getDate();
  		$config 		= &JComponentHelper::getParams('com_feed_manager');
		$config_code	= $config->get('code_update');
		$config_error	= $config->get('max_error',10);
		$config_percent	= $config->get('percentage',80);

		$MailFrom	= $mainframe->getCfg('mailfrom');
		$FromName	= $mainframe->getCfg('fromname');
		$SiteName	= $mainframe->getCfg('sitename');  		
  		for ($i=0;$i<count($this->_arr_jobs);$i++)
  		{
  			$job =& $this->_arr_jobs[$i];

  			if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] do job BEGIN: <b>".$job->title."</b>"); }	
  			if (JRequest::getInt('debug')) { FVB_utility::print_debug(2, "[WORK] link type: <b>".$job->type."</b>"); }
  			$time_now	= JHTML::_('date','','%Y-%m-%d %H:%M:%S');
  			if (JRequest::getInt('debug')) { FVB_utility::print_debug(2, "[WORK] checkout: </b>"); }
  			$query		=	'UPDATE `#__feeds`  
							SET `checked_out` = 1, 
								`checked_out_time`='.$db->Quote($time_now).'
							WHERE `id` ='.$job->id;
			$db->setQuery($query);
			$db->Query();
  			if ($job->type == 'xml')
  			{
  				$this->getXml($job);
  			}elseif ($job->type == 'http')
  			{
  				
  			}
  		if (JRequest::getInt('debug')) { FVB_utility::print_debug(2, "[WORK] Uncheckout: <b>".$time_now."</b>"); }
  			$time_now		= JHTML::_('date','','%Y-%m-%d %H:%M:%S');
			$query	=	"UPDATE `#__feeds`  
							SET `checked_out` = 0, 
								`last_update` = ".$db->Quote($time_now)."
							WHERE `id` =".$job->id;
			$db->setQuery($query);
			$db->Query();

  		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] do job END: <b>".$job->title."</b><hr />"); }
  		if (JRequest::getInt('debug')) { FVB_utility::print_debug(1, "[WORK] remove older content: <b>".$job->title."</b><hr />"); }
//			numberStore
//		find new
			$max_store	=	$job->numberStore;
  			$query	=	'SELECT id FROM `#__fcontent` '.
						' WHERE fid = '. $db->quote($job->feedId).
						' ORDER BY `cdate` DESC '.
						' LIMIT 0 ,'.$max_store;
  			$db->setQuery($query);
//  			echo $db->getQuery();
//  			echo '<hr />';
  			$arr_result	=	$db->loadResultArray();
  			$id	=	implode(',',$arr_result);
 //		find old			
  			$query	=	'SELECT id FROM `#__fcontent` '.
						' WHERE fid = '. $db->quote($job->feedId).
  						'	 AND id NOT IN ('.$id.')';
  			$db->setQuery($query);
//  			echo $db->getQuery();
//  			echo '<hr />';
  			$arr_result	=	$db->loadResultArray();  			
  			$id	=	implode(',',$arr_result);

			if (count($arr_result))
			{
	//		remove old
				$query	=	'DELETE FROM `#__fcontent` '.
								' WHERE fid = '. $db->quote($job->feedId).
								'	 AND id IN ('.$id.')';
				$db->setQuery($query);
//				echo $db->getQuery();
//				echo '<hr />';
				$db->Query();
	//		remove images			
				$query	=	'DELETE FROM `#__fmedia` '.
								' WHERE cid IN ('.$id.')';
				$db->setQuery($query);
//				echo $db->getQuery();
//				echo '<hr />';
				
				$db->Query();				
				$query	=	'UPDATE `#__fcontent_receive` '.
								'	SET state = -1'.
								' WHERE cid IN ('.$id.')';
				$db->setQuery($query);
//				echo $db->getQuery();
//				echo '<hr />';				
				$db->Query();
			}
  		}
  		$return = true;
  		return $return;
  	}
	function getXml($job)
	{
		$db		=	JFactory::getDBO();
		$browser = new phpWebHacks();
		JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables');
		 
	if (JRequest::getInt('debug')) { FVB_utility::print_debug(3, "[WORK] Get source xml: <b>".$job->link ."</b>"); }
		$options['rssUrl']		= $job->link;
		$options['cache_time']	= 60;
		$rssDoc =& JFactory::getXMLparser('RSS', $options);
		if (!$rssDoc)	return	FALSE;
		$items	=	$rssDoc->get_items();
		$arr_links	=	array();
		$arr_titles	=	array();
		$arr_dates	=	array();
		$arr_intros	=	array();
		$arr_id	=	array();
			foreach ($items as $item) {
				$arr_links[] 	= 	$item->get_link();
				$arr_id[]		= 	$db->quote(md5($item->get_link()));
				$arr_titles[] 	= 	$item->get_title();
				$arr_dates[] 	= 	$item->get_date();
				$intro 			= 	$item->get_description();

				if($job->find_replace_intros){
					$arr_intros[] = FVB_Find_Replace::find_replace($intro, explode("\r\n", $job->find_replace_intros ));
				}
			}
			$mess	=	'Total link: '. count($arr_links);
	if (JRequest::getInt('debug')) { FVB_utility::print_debug(3, "[WORK] result from xml: <b>".$mess ."</b>"); }
			$FVB_utility = new FVB_utility();
			$aid	=	implode(',',$arr_id);
			 $query = "SELECT id_original
			 			FROM #__fcontent 
						WHERE id_original in($aid)";
                $db->setQuery($query);
                $arr_result     =       $db->loadResultArray();
			
			for ($i=0; $i<count($arr_links); $i++)
			{
				if (JRequest::getInt('debug')) echo '<hr />';
				if (count($arr_result) && in_array(md5($arr_links[$i]),$arr_result))
                {
                	if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, " <b>[$i]</b> [WORK] article is existing: <b>".$arr_links[$i] ."</b>: $arr_titles[$i]"); }
                        continue;
                }
				if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] get full from: <b>".$arr_links[$i] ."</b>: $arr_titles[$i]"); }
				$link	=	$arr_links[$i];
				$response	=	$browser->get($link);
				$str_real_url = $browser->get_addressbar();
				$charset = $browser->get_charset();
				if (!preg_match($job->getFull_reg, $response, $matches)) {
				if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] invalid get full: <b>".$arr_links[$i] ."</b>: $arr_titles[$i]"); }
					continue;
				}
				$str_full = $matches[$job->getFull_sub];
				$str_full = $FVB_utility->charset_process($str_full, $charset);
				
				$resource_url = new FVB_Resource_Url($str_full, $link);
				//Process link urls (href)
				$str_full = $resource_url->process_href();
				
				//Process image source urls (src)
				$str_full = $resource_url->process_src();
					//Find and replace here 
				if($job->find_replace_fulls){
					$str_full = FVB_Find_Replace::find_replace($str_full, explode("\r\n", $job->find_replace_fulls));
				}
				$root		=	$str_real_url;
				$arr_Isrc 	= 	array();
				$arr_Ititle = 	array();
				if ($job->getImage_reg) {				
					if (preg_match_all($job->getImage_reg, $str_full, $matches))
					{
						if ($job->getISrc_sub)
						{
							$arr_Isrc = $matches[$job->getISrc_sub];
							for ($j = 0; $j < count($arr_Isrc); $j++){
									$resource_url = new FVB_Resource_Url($arr_Isrc[$j], $str_real_url);
									//Process link urls (href)
									$arr_Isrc[$j] = $resource_url->process_single_url();
								}
							}
						if ($job->getITitle_sub)
						{
							$arr_Ititle = $matches[$job->getITitle_sub];
							for ($j = 0; $j < count($arr_Ititle); $j++){
								if($job->find_replace_images){
									$arr_Ititle[$j] = FVB_Find_Replace::find_replace($arr_Ititle[$j], explode("\r\n", $job->find_replace_images));
								}
							}
						}	
					}					
				}else 
				{					
					$this->process_image($str_full, $root, $arr_Isrc);
				}
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] process images: <b>".$arr_links[$i] ."</b>"); }
				$arr_Isrc1	=	array();
				$this->process_image($arr_intros[$i], $root, $arr_Isrc1);
				for ($j=0; $j<count($arr_Isrc1); $j++)
				{
					array_unshift($arr_Ititle,$arr_titles[$i]);
				}
				
				$arr_objImage	=	array();
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] get images BEGIN"); }				
				mosGetImages($arr_intros[$i], $arr_titles[$i], $arr_Isrc1 ,$arr_objImage, $job->pathImage , $job->linkImage);
				mosGetImages($str_full, $arr_titles[$i], $arr_Isrc ,$arr_objImage, $job->pathImage , $job->linkImage);
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] get images END: <b>".count($arr_objImage) ."</b>"); }
				$href	=	new href();
				$date = JFactory::getDate();
				$obj_content	=	new stdClass();
				$obj_content->id_original	=	md5($arr_links[$i]);
				$obj_content->secname	=	$job->secName;
				$obj_content->catname	=	$job->catName;
				$obj_content->secid		=	$job->secid;
				$obj_content->catid		=	$job->catid;
				$obj_content->fid		=	$job->feedId;
				$obj_content->title		=	$arr_titles[$i];
				$obj_content->alias		=	$href->take_file_name($obj_content->title);
				$obj_content->introtext	=	mostidy_clean($arr_intros[$i]);
				$obj_content->fulltext	=	mostidy_clean($str_full);
				$obj_content->cdate		=	date('Y-m-d H:i:s');
				$obj_content->mdate		=	date('Y-m-d H:i:s');
				$time	=	 strtotime($arr_dates[$i]);
				$obj_content->date_original	=	date('Y-m-d H:i:s',$time);
				
				if (count($arr_objImage))
				{
					$obj_content->urlThumb	=	$arr_objImage[0]->url;
					$obj_content->pathThumb	=	$arr_objImage[0]->path;
				}
				$obj_content->sourceUrl	=	$arr_links[$i];
				$obj_content->state		=	1;
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] update content to database"); }	
			 	$fmtsql = "INSERT INTO `#__fcontent` SET %s ON DUPLICATE KEY UPDATE  %s  ";
		        $insert = array();
		        $update = array();
		        foreach (get_object_vars( $obj_content ) as $k => $v) {
		                if (is_array($v) or is_object($v) or $v === NULL) {
		                        continue;
		                }
		                if ($k[0] == '_') { // internal field
		                        continue;
		                }               
		                $insert[] = $db->NameQuote( $k ).' = '.$db->Quote( $v );
		                if ($k != 'id_original') {
		                        $update[] = $db->NameQuote( $k ).' = '.$db->Quote( $v );
		                }               
        		}
		        $db->setQuery( sprintf( $fmtsql, implode( ",", $insert ) ,  implode( ",", $update ) ) );
		        if (!$db->query()) {
		                $messege        =       $db->getQuery();		                
		                return false;
		        }
		         $cid = mysql_insert_id();
			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] insert into Fcontent_receive"); }
		        
		         $row 				=& JTable::getInstance('Fcontent_receive','Table');
		         $row->cid			=	$cid;
		         $row->title		=	$arr_titles[$i];
		         $row->SourceURL	=	$arr_links[$i];
		         $row->fid			=	$job->feedId;
		         $row->state		=	1;
		         $row->store();

			if (JRequest::getInt('debug')) { FVB_utility::print_debug(4, "[WORK] update images to database : <b> total images: ".count($arr_objImage) ."</b>"); }
		         //  store images		        
				for ($j=0; $j<count($arr_objImage); $j++)
				{
					$date = JFactory::getDate();
			         $row =& JTable::getInstance('Fmedia','Table');
			         $row->path			=	$arr_objImage[$j]->path;
			         $row->url			=	$arr_objImage[$j]->url;
			         $row->sourceUrl	=	$arr_objImage[$j]->sourceUrl;
			         if (isset($arr_Ititle[$j]))
			        	$row->title		=	$arr_Ititle[$j];
			         $row->ordering		=	$j;
			         $row->cdate		=	 $date->toMySQL();
			         $row->mdate		=	 $date->toMySQL();
			        
			         $row->state		=	1;
			         $row->cid			=	$cid;			        
						$fmtsql = "INSERT INTO `#__fmedia` SET %s ON DUPLICATE KEY UPDATE  %s  ";
				        $insert = array();
				        $update = array();
				        foreach (get_object_vars( $row ) as $k => $v) {
				                if (is_array($v) or is_object($v) or $v === NULL) {
				                        continue;
				                }
				                if ($k[0] == '_') { // internal field
				                        continue;
				                }               
				                $insert[] = $db->NameQuote( $k ).' = '.$db->Quote( $v );
				                if ($k != 'cid' || $k!= 'sourceUrl' || $k != 'cdate') {
				                        $update[] = $db->NameQuote( $k ).' = '.$db->Quote( $v );
				                }               
		        		}
				        $db->setQuery( sprintf( $fmtsql, implode( ",", $insert ) ,  implode( ",", $update ) ) );
				        if (!$db->query()) {
				                $messege        =       $db->getQuery();		                
				                return false;
				        }
				}
			}
			
		$number	=	count($arr_titles);	
	}
	
	function process_image(&$content, $root, &$arrSrc = array())
	{
		$href   =	new href();
		if(preg_match_all('/<img.*?(src=([^"\'].*?))(\s|\/>|>)/im', $content, $matches)){
		        for ($j = 0; $j < count($matches[1]); $j++){
		                $matches[2][$j] =       $href->process_url($matches[2][$j],$root);
		                $content = str_replace($matches[1][$j], 'src="'. $matches[2][$j] .'"', $content);
		        }
		}
		//find all href value in a tag (with ')
		if(preg_match_all('/<img.*?(src=\'(.*?)\')/im', $content, $matches)){
		        for ($j = 0; $j < count($matches[1]); $j++){
		                $matches[2][$j] =       $href->process_url($matches[2][$j],$root);
		                $content= str_replace($matches[1][$j], 'src="'. $matches[2][$j] .'"', $content);
		        }
		}			        
		if(preg_match_all('/<img.*?(src="(.*?)")/ism', $content, $matches)){
				 $arrSrc =		$matches[2];
		}
		
	}
}
